1   /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
2   package org.apache.lucene.queryparser.classic;
3   
4   import java.io.StringReader;
5   import java.util.ArrayList;
6   import java.util.List;
7   import java.util.Locale;
8   
9   import org.apache.lucene.analysis.Analyzer;
10  import org.apache.lucene.document.DateTools;
11  import org.apache.lucene.search.BooleanClause;
12  import org.apache.lucene.search.Query;
13  import org.apache.lucene.search.TermRangeQuery;
14  import org.apache.lucene.search.TermQuery;
15  
16  /**
17   * This class is generated by JavaCC.  The most important method is
18   * {@link #parse(String)}.
19   *
20   * The syntax for query strings is as follows:
21   * A Query is a series of clauses.
22   * A clause may be prefixed by:
23   * <ul>
24   * <li> a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating
25   * that the clause is required or prohibited respectively; or
26   * <li> a term followed by a colon, indicating the field to be searched.
27   * This enables one to construct queries which search multiple fields.
28   * </ul>
29   *
30   * A clause may be either:
31   * <ul>
32   * <li> a term, indicating all the documents that contain this term; or
33   * <li> a nested query, enclosed in parentheses.  Note that this may be used
34   * with a <code>+</code>/<code>-</code> prefix to require any of a set of
35   * terms.
36   * </ul>
37   *
38   * Thus, in BNF, the query grammar is:
39   * <pre>
40   *   Query  ::= ( Clause )*
41   *   Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
42   * </pre>
43   *
44   * <p>
45   * Examples of appropriately formatted queries can be found in the <a
46   * href="{@docRoot}/org/apache/lucene/queryparser/classic/package-summary.html#package_description">query syntax
47   * documentation</a>.
48   * </p>
49   *
50   * <p>
51   * In {@link TermRangeQuery}s, QueryParser tries to detect date values, e.g.
52   * <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches
53   * for "date" fields between 2005-06-01 and 2005-06-04. Note that the format
54   * of the accepted input depends on {@link #setLocale(Locale) the locale}.
55   * A {@link org.apache.lucene.document.DateTools.Resolution} has to be set,
56   * if you want to use {@link DateTools} for date conversion.
57   * </p>
58   * <p>
59   * The date resolution that shall be used for RangeQueries can be set
60   * using {@link #setDateResolution(DateTools.Resolution)}
61   * or {@link #setDateResolution(String, DateTools.Resolution)}. The former
62   * sets the default date resolution for all fields, whereas the latter can
63   * be used to set field specific date resolutions. Field specific date
64   * resolutions take, if set, precedence over the default date resolution.
65   * </p>
66   * <p>
67   * If you don't use {@link DateTools} in your index, you can create your own
68   * query parser that inherits QueryParser and overwrites
69   * {@link #getRangeQuery(String, String, String, boolean, boolean)} to
70   * use a different method for date conversion.
71   * </p>
72   *
73   * <p>Note that QueryParser is <em>not</em> thread-safe.</p> 
74   * 
75   * <p><b>NOTE</b>: there is a new QueryParser in contrib, which matches
76   * the same syntax as this class, but is more modular,
77   * enabling substantial customization to how a query is created.
78   */
79  public class QueryParser extends QueryParserBase implements QueryParserConstants {
80    /** The default operator for parsing queries.
81     * Use {@link QueryParserBase#setDefaultOperator} to change it.
82     */
83    static public enum Operator { OR, AND }
84  
85    /** Create a query parser.
86     *  @param f  the default field for query terms.
87     *  @param a   used to find terms in the query text.
88     */
89     public QueryParser(String f, Analyzer a) {
90      this(new FastCharStream(new StringReader("")));
91      init(f, a);
92    }
93  
94  // *   Query  ::= ( Clause )*
95  // *   Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
96    final public int Conjunction() throws ParseException {
97    int ret = CONJ_NONE;
98      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
99      case AND:
100     case OR:
101       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
102       case AND:
103         jj_consume_token(AND);
104             ret = CONJ_AND;
105         break;
106       case OR:
107         jj_consume_token(OR);
108               ret = CONJ_OR;
109         break;
110       default:
111         jj_la1[0] = jj_gen;
112         jj_consume_token(-1);
113         throw new ParseException();
114       }
115       break;
116     default:
117       jj_la1[1] = jj_gen;
118       ;
119     }
120     {if (true) return ret;}
121     throw new Error("Missing return statement in function");
122   }
123 
124   final public int Modifiers() throws ParseException {
125   int ret = MOD_NONE;
126     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
127     case NOT:
128     case PLUS:
129     case MINUS:
130       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
131       case PLUS:
132         jj_consume_token(PLUS);
133               ret = MOD_REQ;
134         break;
135       case MINUS:
136         jj_consume_token(MINUS);
137                  ret = MOD_NOT;
138         break;
139       case NOT:
140         jj_consume_token(NOT);
141                ret = MOD_NOT;
142         break;
143       default:
144         jj_la1[2] = jj_gen;
145         jj_consume_token(-1);
146         throw new ParseException();
147       }
148       break;
149     default:
150       jj_la1[3] = jj_gen;
151       ;
152     }
153     {if (true) return ret;}
154     throw new Error("Missing return statement in function");
155   }
156 
157 // This makes sure that there is no garbage after the query string
158   final public Query TopLevelQuery(String field) throws ParseException {
159   Query q;
160     q = Query(field);
161     jj_consume_token(0);
162     {if (true) return q;}
163     throw new Error("Missing return statement in function");
164   }
165 
166   final public Query Query(String field) throws ParseException {
167   List<BooleanClause> clauses = new ArrayList<BooleanClause>();
168   Query q, firstQuery=null;
169   int conj, mods;
170     mods = Modifiers();
171     q = Clause(field);
172     addClause(clauses, CONJ_NONE, mods, q);
173     if (mods == MOD_NONE)
174         firstQuery=q;
175     label_1:
176     while (true) {
177       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
178       case AND:
179       case OR:
180       case NOT:
181       case PLUS:
182       case MINUS:
183       case BAREOPER:
184       case LPAREN:
185       case STAR:
186       case QUOTED:
187       case TERM:
188       case PREFIXTERM:
189       case WILDTERM:
190       case REGEXPTERM:
191       case RANGEIN_START:
192       case RANGEEX_START:
193       case NUMBER:
194         ;
195         break;
196       default:
197         jj_la1[4] = jj_gen;
198         break label_1;
199       }
200       conj = Conjunction();
201       mods = Modifiers();
202       q = Clause(field);
203       addClause(clauses, conj, mods, q);
204     }
205       if (clauses.size() == 1 && firstQuery != null)
206         {if (true) return firstQuery;}
207       else {
208   {if (true) return getBooleanQuery(clauses);}
209       }
210     throw new Error("Missing return statement in function");
211   }
212 
213   final public Query Clause(String field) throws ParseException {
214   Query q;
215   Token fieldToken=null, boost=null;
216     if (jj_2_1(2)) {
217       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
218       case TERM:
219         fieldToken = jj_consume_token(TERM);
220         jj_consume_token(COLON);
221                                field=discardEscapeChar(fieldToken.image);
222         break;
223       case STAR:
224         jj_consume_token(STAR);
225         jj_consume_token(COLON);
226                       field="*";
227         break;
228       default:
229         jj_la1[5] = jj_gen;
230         jj_consume_token(-1);
231         throw new ParseException();
232       }
233     } else {
234       ;
235     }
236     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
237     case BAREOPER:
238     case STAR:
239     case QUOTED:
240     case TERM:
241     case PREFIXTERM:
242     case WILDTERM:
243     case REGEXPTERM:
244     case RANGEIN_START:
245     case RANGEEX_START:
246     case NUMBER:
247       q = Term(field);
248       break;
249     case LPAREN:
250       jj_consume_token(LPAREN);
251       q = Query(field);
252       jj_consume_token(RPAREN);
253       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
254       case CARAT:
255         jj_consume_token(CARAT);
256         boost = jj_consume_token(NUMBER);
257         break;
258       default:
259         jj_la1[6] = jj_gen;
260         ;
261       }
262       break;
263     default:
264       jj_la1[7] = jj_gen;
265       jj_consume_token(-1);
266       throw new ParseException();
267     }
268        {if (true) return handleBoost(q, boost);}
269     throw new Error("Missing return statement in function");
270   }
271 
272   final public Query Term(String field) throws ParseException {
273   Token term, boost=null, fuzzySlop=null, goop1, goop2;
274   boolean prefix = false;
275   boolean wildcard = false;
276   boolean fuzzy = false;
277   boolean regexp = false;
278   boolean startInc=false;
279   boolean endInc=false;
280   Query q;
281     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
282     case BAREOPER:
283     case STAR:
284     case TERM:
285     case PREFIXTERM:
286     case WILDTERM:
287     case REGEXPTERM:
288     case NUMBER:
289       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
290       case TERM:
291         term = jj_consume_token(TERM);
292         break;
293       case STAR:
294         term = jj_consume_token(STAR);
295                        wildcard=true;
296         break;
297       case PREFIXTERM:
298         term = jj_consume_token(PREFIXTERM);
299                              prefix=true;
300         break;
301       case WILDTERM:
302         term = jj_consume_token(WILDTERM);
303                            wildcard=true;
304         break;
305       case REGEXPTERM:
306         term = jj_consume_token(REGEXPTERM);
307                              regexp=true;
308         break;
309       case NUMBER:
310         term = jj_consume_token(NUMBER);
311         break;
312       case BAREOPER:
313         term = jj_consume_token(BAREOPER);
314                            term.image = term.image.substring(0,1);
315         break;
316       default:
317         jj_la1[8] = jj_gen;
318         jj_consume_token(-1);
319         throw new ParseException();
320       }
321       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
322       case FUZZY_SLOP:
323         fuzzySlop = jj_consume_token(FUZZY_SLOP);
324                                 fuzzy=true;
325         break;
326       default:
327         jj_la1[9] = jj_gen;
328         ;
329       }
330       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
331       case CARAT:
332         jj_consume_token(CARAT);
333         boost = jj_consume_token(NUMBER);
334         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
335         case FUZZY_SLOP:
336           fuzzySlop = jj_consume_token(FUZZY_SLOP);
337                                                          fuzzy=true;
338           break;
339         default:
340           jj_la1[10] = jj_gen;
341           ;
342         }
343         break;
344       default:
345         jj_la1[11] = jj_gen;
346         ;
347       }
348        q = handleBareTokenQuery(field, term, fuzzySlop, prefix, wildcard, fuzzy, regexp);
349       break;
350     case RANGEIN_START:
351     case RANGEEX_START:
352       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
353       case RANGEIN_START:
354         jj_consume_token(RANGEIN_START);
355                             startInc=true;
356         break;
357       case RANGEEX_START:
358         jj_consume_token(RANGEEX_START);
359         break;
360       default:
361         jj_la1[12] = jj_gen;
362         jj_consume_token(-1);
363         throw new ParseException();
364       }
365       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
366       case RANGE_GOOP:
367         goop1 = jj_consume_token(RANGE_GOOP);
368         break;
369       case RANGE_QUOTED:
370         goop1 = jj_consume_token(RANGE_QUOTED);
371         break;
372       default:
373         jj_la1[13] = jj_gen;
374         jj_consume_token(-1);
375         throw new ParseException();
376       }
377       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
378       case RANGE_TO:
379         jj_consume_token(RANGE_TO);
380         break;
381       default:
382         jj_la1[14] = jj_gen;
383         ;
384       }
385       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
386       case RANGE_GOOP:
387         goop2 = jj_consume_token(RANGE_GOOP);
388         break;
389       case RANGE_QUOTED:
390         goop2 = jj_consume_token(RANGE_QUOTED);
391         break;
392       default:
393         jj_la1[15] = jj_gen;
394         jj_consume_token(-1);
395         throw new ParseException();
396       }
397       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
398       case RANGEIN_END:
399         jj_consume_token(RANGEIN_END);
400                           endInc=true;
401         break;
402       case RANGEEX_END:
403         jj_consume_token(RANGEEX_END);
404         break;
405       default:
406         jj_la1[16] = jj_gen;
407         jj_consume_token(-1);
408         throw new ParseException();
409       }
410       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
411       case CARAT:
412         jj_consume_token(CARAT);
413         boost = jj_consume_token(NUMBER);
414         break;
415       default:
416         jj_la1[17] = jj_gen;
417         ;
418       }
419           boolean startOpen=false;
420           boolean endOpen=false;
421           if (goop1.kind == RANGE_QUOTED) {
422             goop1.image = goop1.image.substring(1, goop1.image.length()-1);
423           } else if ("*".equals(goop1.image)) {
424             startOpen=true;
425           }
426           if (goop2.kind == RANGE_QUOTED) {
427             goop2.image = goop2.image.substring(1, goop2.image.length()-1);
428           } else if ("*".equals(goop2.image)) {
429             endOpen=true;
430           }
431           q = getRangeQuery(field, startOpen ? null : discardEscapeChar(goop1.image), endOpen ? null : discardEscapeChar(goop2.image), startInc, endInc);
432       break;
433     case QUOTED:
434       term = jj_consume_token(QUOTED);
435       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
436       case FUZZY_SLOP:
437         fuzzySlop = jj_consume_token(FUZZY_SLOP);
438         break;
439       default:
440         jj_la1[18] = jj_gen;
441         ;
442       }
443       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
444       case CARAT:
445         jj_consume_token(CARAT);
446         boost = jj_consume_token(NUMBER);
447         break;
448       default:
449         jj_la1[19] = jj_gen;
450         ;
451       }
452          q = handleQuotedTerm(field, term, fuzzySlop);
453       break;
454     default:
455       jj_la1[20] = jj_gen;
456       jj_consume_token(-1);
457       throw new ParseException();
458     }
459     {if (true) return handleBoost(q, boost);}
460     throw new Error("Missing return statement in function");
461   }
462 
463   private boolean jj_2_1(int xla) {
464     jj_la = xla; jj_lastpos = jj_scanpos = token;
465     try { return !jj_3_1(); }
466     catch(LookaheadSuccess ls) { return true; }
467     finally { jj_save(0, xla); }
468   }
469 
470   private boolean jj_3R_2() {
471     if (jj_scan_token(TERM)) return true;
472     if (jj_scan_token(COLON)) return true;
473     return false;
474   }
475 
476   private boolean jj_3_1() {
477     Token xsp;
478     xsp = jj_scanpos;
479     if (jj_3R_2()) {
480     jj_scanpos = xsp;
481     if (jj_3R_3()) return true;
482     }
483     return false;
484   }
485 
486   private boolean jj_3R_3() {
487     if (jj_scan_token(STAR)) return true;
488     if (jj_scan_token(COLON)) return true;
489     return false;
490   }
491 
492   /** Generated Token Manager. */
493   public QueryParserTokenManager token_source;
494   /** Current token. */
495   public Token token;
496   /** Next token. */
497   public Token jj_nt;
498   private int jj_ntk;
499   private Token jj_scanpos, jj_lastpos;
500   private int jj_la;
501   private int jj_gen;
502   final private int[] jj_la1 = new int[21];
503   static private int[] jj_la1_0;
504   static private int[] jj_la1_1;
505   static {
506       jj_la1_init_0();
507       jj_la1_init_1();
508    }
509    private static void jj_la1_init_0() {
510       jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x200000,0x40000,0x6000000,0x80000000,0x10000000,0x80000000,0x60000000,0x40000,0x200000,0x40000,0xfda2000,};
511    }
512    private static void jj_la1_init_1() {
513       jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0,0x0,};
514    }
515   final private JJCalls[] jj_2_rtns = new JJCalls[1];
516   private boolean jj_rescan = false;
517   private int jj_gc = 0;
518 
519   /** Constructor with user supplied CharStream. */
520   protected QueryParser(CharStream stream) {
521     token_source = new QueryParserTokenManager(stream);
522     token = new Token();
523     jj_ntk = -1;
524     jj_gen = 0;
525     for (int i = 0; i < 21; i++) jj_la1[i] = -1;
526     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
527   }
528 
529   /** Reinitialise. */
530   public void ReInit(CharStream stream) {
531     token_source.ReInit(stream);
532     token = new Token();
533     jj_ntk = -1;
534     jj_gen = 0;
535     for (int i = 0; i < 21; i++) jj_la1[i] = -1;
536     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
537   }
538 
539   /** Constructor with generated Token Manager. */
540   protected QueryParser(QueryParserTokenManager tm) {
541     token_source = tm;
542     token = new Token();
543     jj_ntk = -1;
544     jj_gen = 0;
545     for (int i = 0; i < 21; i++) jj_la1[i] = -1;
546     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
547   }
548 
549   /** Reinitialise. */
550   public void ReInit(QueryParserTokenManager tm) {
551     token_source = tm;
552     token = new Token();
553     jj_ntk = -1;
554     jj_gen = 0;
555     for (int i = 0; i < 21; i++) jj_la1[i] = -1;
556     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
557   }
558 
559   private Token jj_consume_token(int kind) throws ParseException {
560     Token oldToken;
561     if ((oldToken = token).next != null) token = token.next;
562     else token = token.next = token_source.getNextToken();
563     jj_ntk = -1;
564     if (token.kind == kind) {
565       jj_gen++;
566       if (++jj_gc > 100) {
567         jj_gc = 0;
568         for (int i = 0; i < jj_2_rtns.length; i++) {
569           JJCalls c = jj_2_rtns[i];
570           while (c != null) {
571             if (c.gen < jj_gen) c.first = null;
572             c = c.next;
573           }
574         }
575       }
576       return token;
577     }
578     token = oldToken;
579     jj_kind = kind;
580     throw generateParseException();
581   }
582 
583   static private final class LookaheadSuccess extends java.lang.Error { }
584   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
585   private boolean jj_scan_token(int kind) {
586     if (jj_scanpos == jj_lastpos) {
587       jj_la--;
588       if (jj_scanpos.next == null) {
589         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
590       } else {
591         jj_lastpos = jj_scanpos = jj_scanpos.next;
592       }
593     } else {
594       jj_scanpos = jj_scanpos.next;
595     }
596     if (jj_rescan) {
597       int i = 0; Token tok = token;
598       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
599       if (tok != null) jj_add_error_token(kind, i);
600     }
601     if (jj_scanpos.kind != kind) return true;
602     if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
603     return false;
604   }
605 
606 
607 /** Get the next Token. */
608   final public Token getNextToken() {
609     if (token.next != null) token = token.next;
610     else token = token.next = token_source.getNextToken();
611     jj_ntk = -1;
612     jj_gen++;
613     return token;
614   }
615 
616 /** Get the specific Token. */
617   final public Token getToken(int index) {
618     Token t = token;
619     for (int i = 0; i < index; i++) {
620       if (t.next != null) t = t.next;
621       else t = t.next = token_source.getNextToken();
622     }
623     return t;
624   }
625 
626   private int jj_ntk() {
627     if ((jj_nt=token.next) == null)
628       return (jj_ntk = (token.next=token_source.getNextToken()).kind);
629     else
630       return (jj_ntk = jj_nt.kind);
631   }
632 
633   private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
634   private int[] jj_expentry;
635   private int jj_kind = -1;
636   private int[] jj_lasttokens = new int[100];
637   private int jj_endpos;
638 
639   private void jj_add_error_token(int kind, int pos) {
640     if (pos >= 100) return;
641     if (pos == jj_endpos + 1) {
642       jj_lasttokens[jj_endpos++] = kind;
643     } else if (jj_endpos != 0) {
644       jj_expentry = new int[jj_endpos];
645       for (int i = 0; i < jj_endpos; i++) {
646         jj_expentry[i] = jj_lasttokens[i];
647       }
648       jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
649         int[] oldentry = (int[])(it.next());
650         if (oldentry.length == jj_expentry.length) {
651           for (int i = 0; i < jj_expentry.length; i++) {
652             if (oldentry[i] != jj_expentry[i]) {
653               continue jj_entries_loop;
654             }
655           }
656           jj_expentries.add(jj_expentry);
657           break jj_entries_loop;
658         }
659       }
660       if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
661     }
662   }
663 
664   /** Generate ParseException. */
665   public ParseException generateParseException() {
666     jj_expentries.clear();
667     boolean[] la1tokens = new boolean[33];
668     if (jj_kind >= 0) {
669       la1tokens[jj_kind] = true;
670       jj_kind = -1;
671     }
672     for (int i = 0; i < 21; i++) {
673       if (jj_la1[i] == jj_gen) {
674         for (int j = 0; j < 32; j++) {
675           if ((jj_la1_0[i] & (1<<j)) != 0) {
676             la1tokens[j] = true;
677           }
678           if ((jj_la1_1[i] & (1<<j)) != 0) {
679             la1tokens[32+j] = true;
680           }
681         }
682       }
683     }
684     for (int i = 0; i < 33; i++) {
685       if (la1tokens[i]) {
686         jj_expentry = new int[1];
687         jj_expentry[0] = i;
688         jj_expentries.add(jj_expentry);
689       }
690     }
691     jj_endpos = 0;
692     jj_rescan_token();
693     jj_add_error_token(0, 0);
694     int[][] exptokseq = new int[jj_expentries.size()][];
695     for (int i = 0; i < jj_expentries.size(); i++) {
696       exptokseq[i] = jj_expentries.get(i);
697     }
698     return new ParseException(token, exptokseq, tokenImage);
699   }
700 
701   /** Enable tracing. */
702   final public void enable_tracing() {
703   }
704 
705   /** Disable tracing. */
706   final public void disable_tracing() {
707   }
708 
709   private void jj_rescan_token() {
710     jj_rescan = true;
711     for (int i = 0; i < 1; i++) {
712     try {
713       JJCalls p = jj_2_rtns[i];
714       do {
715         if (p.gen > jj_gen) {
716           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
717           switch (i) {
718             case 0: jj_3_1(); break;
719           }
720         }
721         p = p.next;
722       } while (p != null);
723       } catch(LookaheadSuccess ls) { }
724     }
725     jj_rescan = false;
726   }
727 
728   private void jj_save(int index, int xla) {
729     JJCalls p = jj_2_rtns[index];
730     while (p.gen > jj_gen) {
731       if (p.next == null) { p = p.next = new JJCalls(); break; }
732       p = p.next;
733     }
734     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
735   }
736 
737   static final class JJCalls {
738     int gen;
739     Token first;
740     int arg;
741     JJCalls next;
742   }
743 
744 }